package org.ccay.enumerable.mybatis;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.ccay.enumerable.EnumItem;
import org.ccay.enumerable.EnumUtil;

public class EnumItemTypeHandler<E extends EnumItem<E>> extends BaseTypeHandler<E>{
	
	/**
	 * 枚举类型Class
	 */
	private Class<E> classType;
	
	public EnumItemTypeHandler(Class<E> classType){
		if (classType == null ) {
			throw new IllegalArgumentException("Type argument cannot be null");
		}
		this.classType = classType;
	}
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {
		if (jdbcType == null) {
			ps.setString(i, parameter.getValue());
		} else {
			ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE); // see r3589
		}
	}

	@Override
	public E getNullableResult(ResultSet rs, String columnName) throws SQLException {
		 String s = rs.getString(columnName);
		 return s == null ? null : findEnumItem(s);
	}
	

	@Override
	public E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		 String s = rs.getString(columnIndex);
		 return s == null ? null : findEnumItem(s);
	}

	@Override
	public E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		 String s = cs.getString(columnIndex);
		 return s == null ? null : findEnumItem(s);
	}
	
	public E findEnumItem(String value){
		if(!classType.isInterface()){
			return (E) EnumUtil.getInstance().getByTypeValue(classType.getSimpleName(), value);
		}
		//Can't found type info so just save value and process by Interceptor later.
		return (E) new JustValueEnumItem(value);
	}
	
	public Class<E> getClassType() {
		return classType;
	}
}
